package com.yami.shop.api.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yami.shop.bean.dto.ScanCodeDto;
import com.yami.shop.bean.event.ReproductionQrcodeEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.SendUserDropsParam;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.bean.vo.CategoryVO;
import com.yami.shop.bean.vo.ScanCodeDataVo;
import com.yami.shop.common.bean.Minio;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.OssMultipartFile;
import com.yami.shop.common.util.StringUtils;
import com.yami.shop.common.util.pdfUtil.PdfUtils;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.mystery.common.service.ActivityPresellService;
import com.yami.shop.nft.common.service.NftDawService;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 *
 */
@RequestMapping("/p/ScanCodeAirdrop")
@RestController
@Slf4j
@Tag(name = "春节扫码空投接口")
public class ScanCodeAirdropController {

    @Autowired
    private AirdropTaskService airdropTaskService;

    @Autowired
    private ProductService productService;
    @Autowired
    private ProdNftService prodNftService;
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private ChannelUserRelationRecordService channelUserRelationRecordService;

    @Autowired
    private BusinessNftService businessNftService;

    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private ReproductionQrcodeService reproductionQrcodeService;
    @Autowired
    private UserService userService;
    @Autowired
    private ShopConfig shopConfig;
    @Autowired
    private AttachFileService attachFileService;
    @Autowired
    private NftDawService nftDawService;
    @Autowired
    private ActivityPresellService activityPresellService;


    /**
     * 扫码空投
     */
    @PostMapping("/scanCodeAirdropByProdId")
    @Operation(summary =  "扫码空投", description = "扫码空投")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<String> scanCodeAirdropByProdId(@RequestBody ScanCodeDto scanCodeDto) {
        ReproductionQrcode reproductionQrcode = reproductionQrcodeService.getOne(new QueryWrapper<ReproductionQrcode>().eq("qrcode_code", scanCodeDto.getQrcodeCode()));
        if(reproductionQrcode.getStatus().equals("1")){
            return ServerResponseEntity.showFailMsg("已经登记认证");
        }
        // 判断数字证书
        String userId = SecurityUtils.getUser().getUserId();
        Product productInfo = productService.getProductInfo(scanCodeDto.getProdId());
        if (productInfo == null) {
            return ServerResponseEntity.showFailMsg("商品不存在");
        }
        //1判断是否导入该商品对应的链地址 有|没有导入
        if (!channelUserRelationRecordService.isHasDTCAddress(userId, productInfo.getChain(), productInfo.getChannelCode())) {
            channelUserRelationRecordService.createDtcAddress(userId, productInfo.getChain(), productInfo.getChannelCode());
        }

        // 黄金公司增加需求 --  判断是否有币 如果没 调用铸币接口
        // 获取经销商ID
        if(ObjectUtil.isNotEmpty(reproductionQrcode.getActivityId())){
            ShopDealer shopDealer = activityPresellService.getDealerByActivityId(reproductionQrcode.getActivityId());
            Long isHaveCoin = nftDawService.asyncIsHaveCoin(scanCodeDto.getMainProdId(), 0,shopDealer.getDealerCode(),false);
            if(isHaveCoin <= 0){
                return ServerResponseEntity.showFailMsg("数字证书尚未准备好,请联系销售方!");
            }
        }

        //2 任务空投逻辑
        UserUpdateParam param = new UserUpdateParam();
        // 商品信息
        List<SendUserDropsParam> userDropsParams = new ArrayList<>();
        SendUserDropsParam sendUserDropsParam = new SendUserDropsParam();
        sendUserDropsParam.setTargetId(productInfo.getProdId());
        sendUserDropsParam.setType(0);
        sendUserDropsParam.setNums(1);
        userDropsParams.add(sendUserDropsParam);
        param.setDrops(userDropsParams);
        param.setUserIds(Collections.singletonList(userId));
        param.setBusinessType(2);
        param.setMainProdId(scanCodeDto.getMainProdId());
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(productInfo.getShopId());
        businessNftService.bindDropById(param, shopDetail);
        // 证书空投
        //3广播成功消息DOTO
        eventPublisher.publishEvent(new ReproductionQrcodeEvent(scanCodeDto.getQrcodeType(),scanCodeDto.getQrcodeCode()));
        // 获取base64
        Product mainProductInfo = productService.getProductInfo(scanCodeDto.getMainProdId());
        String base64 = getBase64(mainProductInfo,"","","");

        return ServerResponseEntity.success(base64);
    }

    private String getBase64(Product productInfo,String worksNo,String tokenId,String time) {
        try{
            Map<String, Object> keyWordMap = new HashMap<>();

            keyWordMap.put("name","");
            try {
                User user = userService.getUserByUserId(SecurityUtils.getUser().getUserId());
                keyWordMap.put("name",user.getRealName());
            }catch (Exception e){
                e.printStackTrace();
            }
            keyWordMap.put("worksNo","待上链");
            if (StringUtils.isNotEmpty(worksNo)) {
                keyWordMap.put("worksNo",worksNo);
            }
            keyWordMap.put("worksTypeName","字画");
            Map<String,String> imageMap = new HashMap<>();
            Minio minio = shopConfig.getMinio();
            keyWordMap.put("worksName",productInfo.getProdName());
            imageMap.put("worksImg",minio.getEndpoint() + "/" + minio.getBucketName() + "/" + productInfo.getPic());
            ProdNft prodNft = prodNftService.getDataByProdId(productInfo.getProdId());
            keyWordMap.put("autherName",prodNft.getAuthorName());
            keyWordMap.put("tokenId","待上链");
            if (StringUtils.isNotEmpty(tokenId)) {
                keyWordMap.put("tokenId",tokenId);
            }
            keyWordMap.put("time","待上链");
            if (StringUtils.isNotEmpty(time)) {
                keyWordMap.put("time",time);
            }

            URL url = new URL(minio.getEndpoint() + "/" + minio.getBucketName() + "/cqdj.pdf");
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();
            ByteArrayOutputStream qrOutputStream = new ByteArrayOutputStream();
            PdfUtils.generatePdf(urlConnection.getInputStream(), qrOutputStream, keyWordMap,imageMap,35f);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ByteArrayOutputStream scaleOutputStream = new ByteArrayOutputStream();
            //保存图片
            PDDocument document = PDDocument.load(qrOutputStream.toByteArray());
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            BufferedImage image = pdfRenderer.renderImageWithDPI(0, 300); // 使用300dpi解析第一页，可以自行调整dpi大小
            ImageIO.write(image, "JPEG", outputStream);
            MultipartFile ossMultipartFile = new OssMultipartFile("111.jpg", ".jpg", outputStream.toByteArray());
            ImgUtil.scale(ossMultipartFile.getInputStream(),scaleOutputStream,0.1f);

            return attachFileService.uploadFile(scaleOutputStream.toByteArray(), UUID.randomUUID() + ".jpg");
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }

    @PostMapping("getScanCodeData")
    @Operation(summary =  "获取复刻画页面数据", description = "获取复刻画页面数据")
    public ServerResponseEntity<ScanCodeDataVo> getScanCodeData(@RequestBody ScanCodeDto scanCodeDto){

        ScanCodeDataVo scanCodeDataVo = new ScanCodeDataVo();
        // 查询该二维码是否认证
        ReproductionQrcode reproductionQrcode = reproductionQrcodeService.getOne(new QueryWrapper<ReproductionQrcode>().eq("qrcode_code", scanCodeDto.getQrcodeCode()));
        scanCodeDataVo.setIsAuthentication(reproductionQrcode.getStatus());
        // 获取商品信息
        Product product = productService.getProductById(reproductionQrcode.getProdId());

        BeanUtil.copyProperties(product,scanCodeDataVo);
        ProdNft prodNft = prodNftService.getDataByProdId(reproductionQrcode.getProdId());
        scanCodeDataVo.setAuthorName(prodNft.getAuthorName());
        CategoryVO categoryVO = categoryService.getInfo(product.getShopCategoryId());
        scanCodeDataVo.setCategoryName(categoryVO.getCategoryName());
        scanCodeDataVo.setCertificate(reproductionQrcode.getCertificate());

        return ServerResponseEntity.success(scanCodeDataVo);

    }
}
